package gold.digger;

import java.util.*;

/**
 * Created by fanzhenyu02 on 2021/12/10.
 * common problem solver template.
 */
public class LC2013 {
    public long startExecuteTime = System.currentTimeMillis();


    class DetectSquares {
        Map<String, Integer> memo = new HashMap<>();
        Map<Integer, Set<Integer>> yRecord = new HashMap<>();

        public void add(int[] point) {
            String key = point[0] + "_" + point[1];
            memo.put(key, memo.getOrDefault(key, 0) + 1);
            if (!yRecord.containsKey(point[1])) yRecord.put(point[1], new HashSet<>());
            yRecord.get(point[1]).add(point[0]);
        }

        public int count(int[] point) {
            int cnt = 0;
            // 从四个方向查询
            final Set<Integer> yPoint = yRecord.getOrDefault(point[1], new HashSet<>());
            for (int targetX : yPoint) {
                int len = Math.abs(point[0] - targetX);
                if (len > 0) {
                    cnt += memo.getOrDefault(targetX + "_" + point[1], 0) * memo.getOrDefault(targetX + "_" + (point[1] - len), 0) * memo.getOrDefault(point[0] + "_" + (point[1] - len), 0);
                    cnt += memo.getOrDefault(targetX + "_" + point[1], 0) * memo.getOrDefault(targetX + "_" + (point[1] + len), 0) * memo.getOrDefault(point[0] + "_" + (point[1] + len), 0);
                }
            }

            return cnt;
        }
    }

    class DetectSquares_Other {
        Map<Integer, Map<Integer, Integer>> row2Col = new HashMap<>();

        public void add(int[] point) {
            int x = point[0], y = point[1];
            Map<Integer, Integer> col2Cnt = row2Col.getOrDefault(x, new HashMap<>());
            col2Cnt.put(y, col2Cnt.getOrDefault(y, 0) + 1);
            row2Col.put(x, col2Cnt);
        }

        public int count(int[] point) {
            int x = point[0], y = point[1];
            int ans = 0;
            Map<Integer, Integer> col2Cnt = row2Col.getOrDefault(x, new HashMap<>());
            for (int ny : col2Cnt.keySet()) {
                if (ny == y) continue;
                int c1 = col2Cnt.get(ny);
                int len = y - ny;
                int[] nums = new int[]{x + len, x - len};
                for (int nx : nums) {
                    Map<Integer, Integer> temp = row2Col.getOrDefault(nx, new HashMap<>());
                    int c2 = temp.getOrDefault(y, 0), c3 = temp.getOrDefault(ny, 0);
                    ans += c1 * c2 * c3;
                }
            }
            return ans;
        }
    }


    public void run() {
        DetectSquares detectSquares = new DetectSquares();
        detectSquares.add(new int[]{3, 10});
        detectSquares.add(new int[]{11, 2});
        detectSquares.add(new int[]{3, 2});
        System.out.println(detectSquares.count(new int[]{11, 10}));// 返回 1 。你可以选择：第一个，第二个，和第三个点
        System.out.println(detectSquares.count(new int[]{14, 8}));// 返回 0 。查询点无法与数据结构中的这些点构成正方形。
        detectSquares.add(new int[]{11, 2});    // 允许添加重复的点。
        System.out.println(detectSquares.count(new int[]{11, 10}));// 返回 2 。你可以选择：第一个，第二个，和第三个点 OR 第一个，第三个，和第四个点
    }

    public static void main(String[] args) throws Exception {
        LC2013 an = new LC2013();
        an.run();

        System.out.println("\ncurrent solution total execute time: " + (System.currentTimeMillis() - an.startExecuteTime) + " ms.");
    }
}
